<?
	/**
	 * UCModShorten.php
	 * 短域名服务逻辑
	 *
	 * Copyright (c) 2010 snda.com - Web Development Center
	 * @authos: Gu Shougang <gushougang@snda.com>
	 */
		
	require_once(dirname(__FILE__).'/../../libraries/UCLibKVDB.php');
	require_once(dirname(__FILE__).'/../../config/shorten/UCConfShorten.php');
	
	class UCModShorten
	{
		/**
		 * 构造函数
		 * 调用__construct()
		 */
		public function UCModShorten()
		{
			$this->__construct();
		}
		
		/**
		 * 构造函数
		 */
		public function __construct()
		{
			
		}
		
		/**
		 * 十进制数转其他进制
		 * @param int $decimal 需要被转的十进制数
		 * @param int $jinzhi 需要进行转换的进制类别
		 * @param int $length 转化后的字符长度,如果转出来的字符长度小于$length,则前面补零
		 * @return string
		 */
		public function dec2n($decimal, $jinzhi, $length = 0)
		{
			$result = "";
			
			while($decimal != 0)
			{
				$linshi = $decimal % $jinzhi;
				switch($jinzhi)
				{
					case 2:
						return decbin($decimal);
					case 8:
						return decoct($decimal);
					case 16:
						return dechex($decimal);
					case 36:
						if($linshi >= 10)
						{
							$result .= chr(($linshi + 55));
						}
						else
						{
							$result .= $linshi;
						}
						break;
					case 62:
						if(($linshi >= 10) && ($linshi < 36))
						{
							$result .= chr($linshi + 55);
							break;
						}
						if(($linshi >= 36) && ($linshi < 62))
						{
							$result .= chr($linshi + 61);
							break;
						}
						
						$result .= $linshi;
						break;
					default:
						$result .= $linshi;
						break;
				}
					
				$decimal = intval($decimal / $jinzhi);
			}
			
			for($i = strlen($result); $i < $length; $i++)
			{
				$result .= "0";
			}
			
			return strrev($result);
		}

		/**
		 * 其他进制转十进制数
		 * @param int $number 需要被转的其他进制数
		 * @param int $jinzhi 需要进行转换的进制类别
		 * @param int $length 转化后的字符长度,如果转出来的字符长度小于$length,则前面补零
		 * @return string
		 */
		public function n2dec($number, $jinzhi, $length = 0)
		{
			$decimal = 0;
			for($i = 0;$i <= strlen($number) - 1;$i++)
			{
				$linshi = substr($number, $i, 1);
				switch($jinzhi)
				{
					case 2:
						$decimal = bindec($number);
						$i = strlen($number) + 1;
						break;
					case 8:
						$decimal = octdec($number);
						$i = strlen($number) + 1;
						break;
					case 16:
						$decimal = hexdec($number);
						$i = strlen($number) + 1;
						break;
					case 36:
						if(ord($linshi) <= 57)
						{
							$decimal += (ord($linshi) - 48) * pow($jinzhi, strlen($number) - $i - 1);
						}
						else
						{
							$decimal = $decimal + (ord($linshi) - 55) * pow($jinzhi, strlen($number) - $i - 1);
						}
						break;
					case 62:
						if(ord($linshi) <= 57)
						{
							$decimal += $linshi * pow($jinzhi, strlen($number) - $i - 1);
						}
						elseif((ord($linshi) >= 65) && (ord($linshi) <= 90))
						{
							$decimal += (ord($linshi) - 55) * pow($jinzhi, strlen($number) - $i - 1);
						}
						else
						{
							$decimal += (ord($linshi) - 61) * pow($jinzhi, strlen($number) - $i - 1);
						}
						break;
				}
			}
			return $decimal;
		}

		/**
		 * 根据给定的长域名L获取数据库中的短域名
		 * @param string $longUrl 给定的长域名
		 * @return string
		 */
		public function getShortUrlFromDB($longUrl)
		{
			$longUrl = trim($longUrl);
			if(strlen($longUrl) == 0)
			{
				return '';
			}
			
			if(!is_url($longUrl))
			{
				return '';
			}
			
			$pdo_key = $longUrl;
			$pdo = get_shorten_tt_config('Long_Short', $pdo_key);
			$tt = new UCLibKVDB(UCLibKVDB::$CHANNEL_LONG_SHORT);
			
			$r = unserialize($tt->get($pdo['tb_name']));
			
			return (is_array($r) && strlen($r[0])) ? $r[0] : FALSE;
		}
		
		/**
		 * 将生成的短域名插入数据库
		 * @param string $longUrl 长域名
		 * @param string $shortUrl 短域名
		 * @return boolean
		 */
		public function insertShortUrlToDB($longUrl, $shortUrl)
		{
			$longUrl = trim($longUrl);
			$shortUrl = trim($shortUrl);
			
			if(strlen($longUrl) == 0 || strlen($shortUrl) == 0)
			{
				return FALSE;
			}
			
			if(!is_url($longUrl) || !is_url($shortUrl))
			{
				return FALSE;
			}
			
			$pdo_key = $shortUrl;
			$pdo = get_shorten_tt_config('Short_Long', $pdo_key);
			$tt = new UCLibKVDB(UCLibKVDB::$CHANNEL_SHORT_LONG);			
			$r = $tt->put($pdo['tb_name'], serialize(array($longUrl, time())));
			
			if($r)
			{
				$pdo_key = $longUrl;
				$pdo = get_shorten_tt_config('Long_Short', $pdo_key);
				$tt = new UCLibKVDB(UCLibKVDB::$CHANNEL_LONG_SHORT);
				$r = $tt->put($pdo['tb_name'], serialize(array($shortUrl, time())));
				$tt->close();
				
				return $r ? TRUE : FALSE;
			}
			
			$tt->close();
			return FALSE;
		}
		
		/**
		 * 根据给定的短域名获取数据库中的长域名
		 * @param string $shortUrl 给定的短域名
		 * @return string
		 */
		public function getLongUrlFromDB($shortUrl)
		{
			$shortUrl = trim($shortUrl);
			
			if(strlen($shortUrl) == 0)
			{
				return FALSE;
			}
			
			if(!is_url($shortUrl))
			{
				return FALSE;
			}
			
			$pdo_key = $shortUrl;
			$pdo = get_shorten_tt_config('Short_Long', $pdo_key);
			$tt = new UCLibKVDB(UCLibKVDB::$CHANNEL_SHORT_LONG);
			
			$r = $tt->get($pdo['tb_name']);
			
			if($r === FALSE)
			{
				return FALSE;
			}
			
			return $r;
		}
		
		/**
		 * 获取短域名计数器值
		 * @return string
		 */
		public function getShorUrlCounterFromDB()
		{
			$pdo = get_shorten_tt_config('Short_Counter');
			$tt = new UCLibKVDB(UCLibKVDB::$CHANNEL_SHORT_COUNTER);
			
			$r = $tt->get($pdo['tb_name']);
			
			if($r === FALSE)
			{
				return '';
			}
			
			return $r;
		}
		
		/**
		 * 设置短域名计数器值
		 * @param string $counter 计数器值
		 * @return boolean
		 */
		public function setShorUrlCounterFromDB($counter)
		{
			$counter = trim($counter);
			if(strlen($counter) == 0)
			{
				return FALSE;
			}
			
			$pdo = get_shorten_tt_config('Short_Counter');
			$tt = new UCLibKVDB(UCLibKVDB::$CHANNEL_SHORT_COUNTER);
			
			$r = $tt->put($pdo['tb_name'], $counter);
			
			return $r ? TRUE : FALSE;
		}
		
		/**
		 * 根据长域名生成短域名
		 * @param string $longUrl 长域名
		 * @param int $loop 重试操作计数器
		 * @return string
		 */
		public function makeShortUrlByLongUrl($longUrl, $loop = 0)
		{
			if($loop > (UC_SHORTEN_LOOP - 1))
			{
				return FALSE;
			}
			
			$longUrl = trim($longUrl);
			if(strlen($longUrl) == 0)
			{
				return FALSE;
			}
			
			if(!is_url($longUrl))
			{
				return FALSE;
			}
			
			$shortUrl = $this->getShortUrlFromDB($longUrl);
			if($shortUrl !== FALSE)
			{
				return $shortUrl;
			}
			
			$counter = $this->getShorUrlCounterFromDB();
			if(strlen($counter) == 0)
			{
				$counter = UC_SHORTEN_START_COUNT;
			}
			
			$counter_temp0 = $counter;
			
			$counter_decimal = $this->n2dec($counter, 62);
			$counter_decimal ++;
			$counter = $this->dec2n($counter_decimal, 62);
			
			$counter_temp1 = $this->getShorUrlCounterFromDB();
			if(strlen($counter_temp1) == 0)
			{
				$counter_temp1 = UC_SHORTEN_START_COUNT;
			}
			
			if($counter_temp0 == $counter_temp1)
			{
				$r = $this->setShorUrlCounterFromDB($counter);
				
				if($r)
				{
					$shortUrl = UC_CONF_UC_SDOMAIN .'/'. $counter;
					$r = $this->insertShortUrlToDB($longUrl, $shortUrl);
					
					if($r)
					{
						return $shortUrl;
					}
					
					return FALSE;
				}
				
				return FALSE;	
			}
			else
			{
				$loop++;
				$this->makeShortUrlByLongUrl($longUrl,  $loop);
			}
		}
		
		/**
		 * 短域名统计
		 */
		public function setCountShortUrlFromDB($shortUrl)
		{

		}
	}
?>